package com.d3works.apps.production.service.operationorder;

import com.d3works.apps.production.db.Machine;
import com.d3works.apps.production.db.MachineTool;
import com.d3works.apps.production.db.ManufOrder;
import com.d3works.apps.production.db.OperationOrder;
import com.d3works.apps.production.db.ProdProcessLine;
import com.d3works.apps.production.db.ProdProduct;
import com.d3works.apps.production.db.WorkCenter;
import com.d3works.apps.stock.db.StockMoveLine;
import com.d3works.exception.D3worksException;
import com.google.inject.persist.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

public interface OperationOrderService {

  @Transactional(rollbackOn = {Exception.class})
  public OperationOrder createOperationOrder(ManufOrder manufOrder, ProdProcessLine prodProcessLine)
      throws D3worksException;

  @Transactional(rollbackOn = {Exception.class})
  public OperationOrder createOperationOrder(
      ManufOrder manufOrder,
      int priority,
      WorkCenter workCenter,
      Machine machine,
      MachineTool machineTool,
      ProdProcessLine prodProcessLine)
      throws D3worksException;

  public String computeName(ManufOrder manufOrder, int priority, String operationName);

  /**
   * Generate {@link OperationOrder#toConsumeProdProductList} from the prod process line in param.
   *
   * @param operationOrder
   */
  void createToConsumeProdProductList(OperationOrder operationOrder);

  /**
   * Updates the diff prod product list.
   *
   * @param operationOrder
   * @return the updated operation order
   * @throws D3worksException
   */
  OperationOrder updateDiffProdProductList(OperationOrder operationOrder) throws D3worksException;

  List<Map<String, Object>> chargeByMachineHours(
      LocalDateTime fromDateTime, LocalDateTime toDateTime) throws D3worksException;

  List<Map<String, Object>> chargeByMachineDays(
      LocalDateTime fromDateTime, LocalDateTime toDateTime) throws D3worksException;

  /**
   * Compute the difference between the two lists for the given operation order.
   *
   * @param operationOrder
   * @param prodProductList
   * @param stockMoveLineList
   * @return
   * @throws D3worksException
   */
  List<ProdProduct> createDiffProdProductList(
      OperationOrder operationOrder,
      List<ProdProduct> prodProductList,
      List<StockMoveLine> stockMoveLineList)
      throws D3worksException;
  /**
   * Check the realized consumed stock move lines in operation order has not changed.
   *
   * @param operationOrder an operation order from context.
   * @param oldOperationOrder an operation order from database.
   * @throws D3worksException if the check fails.
   */
  void checkConsumedStockMoveLineList(
      OperationOrder operationOrder, OperationOrder oldOperationOrder) throws D3worksException;

  /**
   * On changing {@link OperationOrder#consumedStockMoveLineList}, we update {@link
   * OperationOrder#diffConsumeProdProductList}, and also the stock move.
   *
   * @param operationOrder
   */
  void updateConsumedStockMoveFromOperationOrder(OperationOrder operationOrder)
      throws D3worksException;

  public void createBarcode(OperationOrder operationOrder);
}
